package sk.openit.xml.jaxp.sax;

import java.io.File;
import java.io.IOException;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

import sk.openit.xml.entity.DbConfig;
import sk.openit.xml.entity.DbConfigTags;
import sk.openit.xml.helpers.JaxpHelpers;

public class DbConfigReader extends DefaultHandler implements DbConfigTags {
	private String fileName;
	private DbConfig config;
	private boolean processed; 
	private String actualTag;
	private boolean startElement;
	
	public DbConfigReader(String fileName) {
		this.fileName = fileName;
		this.processed = false; 
	}
	
	public void process() {
		SAXParserFactory factory = SAXParserFactory.newInstance();
		try {
			SAXParser saxParser = factory.newSAXParser();
			saxParser.parse(new File(fileName), this);
		} catch (ParserConfigurationException e) {
			System.err.println("Wrong SAXParser configuration");			
			e.printStackTrace();
		} catch (SAXException e) {
			System.err.println("Unable to parse XML structure: " + fileName);
			e.printStackTrace();
		} catch (IOException e) {
			System.err.println("Unable to open xml file: " + fileName);
			e.printStackTrace();
		}		
	}
	
	public DbConfig getConfig() {
		return processed ? config : null;
	}

	@Override
	public void startDocument() throws SAXException {
		System.out.println("Start processing XML document");
		
		config = new DbConfig();
		processed = false;
	}

	@Override
	public void endDocument() throws SAXException {
		System.out.println("Finished processing XML document");
		processed = true;
	}

	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		actualTag = qName;
		startElement = true;
		if (CONFIG.equals(actualTag)) {
			Map<String, String> attMaps = JaxpHelpers.processAttributes(attributes);
			config.setDbType(attMaps.get(DB_TYPE));
		}
	}

	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		startElement = false;
	}

	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		String text = new String(ch, start, length);
		if (startElement && HOST.equals(actualTag)) {
			config.setHost(text);
		} else if (startElement && PORT.equals(actualTag)) {
			config.setPort(text);
		} else if (startElement && INSTANCE.equals(actualTag)) {
			config.setInstance(text);
		}
	}
	
	@Override
	public void warning(SAXParseException e) throws SAXException {
		System.err.println("! warning: " + e.getMessage());
	}

	@Override
	public void error(SAXParseException e) throws SAXException {
		System.err.println("!! error: " + e.getMessage());
	}

	@Override
	public void fatalError(SAXParseException e) throws SAXException {
		System.err.println("!!! fatalError: " + e.getMessage());
	}	
}
